package ws.dealform;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Hashtable;
import javax.servlet.http.HttpServletRequest;
import ws.log.*;

/**
 * After gaven a list of the form`s attribution,and a list of Object`s attribution,
 * Call the Class which will get value from the form`s attribution and set the object`s attribution.
 * */
public class SetObjAttrValue {

	
	//Hashtable<String,String> FormToObj;
	Class objClass ;
	Hashtable propertyHash;
	
	/**
	 * The function support int,long,double,Date,boolean.
	 * The Date must be yyyy-MM-dd HH:mm:ss.
	 * The boolean can be true or false and 1 or 0.
	 * @param:
	 * 	obj - the object you must init.
	 *  FormToObj - the compare of Form Attribution and the Object Attribution.
	 *  request	- the HttpServletRequest Object.
	 * @exception:
	 * 	all exception have been written to FormAttrLog.
	 * @return: void
	 * */
	public  void SetTheObjectAttrs(Object obj,Hashtable<String,String>FormToObj,
										HttpServletRequest request){
		
		if(FormToObj.isEmpty()){
			return ;
		}
		/*Get the obj attribution`s name and its description.*/
		objClass = obj.getClass();
		propertyHash = new Hashtable();
		GetObjectAttrsDescrption(objClass,propertyHash);
		
		/*
		 * Get value from request using the FormAttrs`s key name,
		 * and set the Obj value using the FormAttrs`s value name.
		 * */
		Object key=null;
		try{
			for(Iterator its=FormToObj.keySet().iterator();its.hasNext();){
				
				key = its.next();
				String attr = FormToObj.get(key);//get the Obj attribution name
				//Get the attribution`s description.
				String attrafterlower = attr.replaceFirst(attr.substring(0,1), attr.substring(0,1).toLowerCase());
				Class type =(Class) propertyHash.get(attrafterlower);
				Object value = null;
			
				if(type.isAssignableFrom(int.class)){
					value = new Integer((String)request.getParameter((String)key)).intValue();	
				}else if(type.isAssignableFrom(long.class)){
					value = new Long((String)request.getParameter((String)key)).longValue();
				}else if(type.isAssignableFrom(double.class)){
					value = new Double((String)request.getParameter((String)key)).doubleValue();
				}else if(type.isAssignableFrom(Date.class)){
					DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
					value=(Date)formatter.parse((String)request.getParameter((String)key));					
				}else if(type.isAssignableFrom(boolean.class)){
					String temp = (String)request.getParameter((String)key).trim();
					if (temp.equals("true")||temp.equals("1")){
						value = true;
					}else if(temp.equals("false")||temp.equals("0")){
						value = false;
					}else{
						value = null;
					}
				}else{
					value = (String)request.getParameter((String)key);
				}
				Class argTypes[] ={type};  //函数参数类型
				Method m = objClass.getMethod("set"+attr, argTypes); //得到该函数
				Object values[] ={value}; //要调用的函数参数的值
				m.invoke(obj,values);
			}
			
		}catch(ParseException parseEx){
			Log.writeFormAttrLog("Date类型转换错误", parseEx);
		}catch(NoSuchMethodException noSuchMethodEx){
			Log.writeFormAttrLog("没有对应方法", noSuchMethodEx);
		}catch(SecurityException secutiryEx){
			Log.writeFormAttrLog("安全错误人",secutiryEx);
		}catch(IllegalAccessException illAccessEx){
			Log.writeFormAttrLog("非法访问错误", illAccessEx);
		}catch(IllegalArgumentException illArgEx){
			Log.writeFormAttrLog("错误参数", illArgEx);
		}catch(InvocationTargetException invocationTargetEx){
			Log.writeFormAttrLog("invocationTargetEx错误", invocationTargetEx);
		}catch(NullPointerException nullPointerEx){
			Log.writeFormAttrLog("空指针:PageAttr->"+(String)key+"<==>ObjAttr->"+FormToObj.get(key), nullPointerEx);
		}
		
		
	}

	/**
	 * Get obj`s attribution`s description.
	 * */
	private void GetObjectAttrsDescrption(Class objClass,Hashtable propertyHash){
		try{
			BeanInfo beaninfo = Introspector.getBeanInfo(objClass);
			PropertyDescriptor prodes[] = beaninfo.getPropertyDescriptors();
			if(prodes!=null){
				for(int i=0; i<prodes.length;i++){
					propertyHash.put(prodes[i].getName(), prodes[i].getPropertyType());	
				}
			}
		}catch(Exception e){
			Log.writeFormAttrLog("得到对象属性描述", e);
		}
		
	}
}
